#pragma once
#ifndef MEMORY_H
#define MEMORY_H

#include "SDRAM.h"
#include <Logger.h>
#include <vector>

// #define Malloc(type,n) (type *)memory.allocate((n)*sizeof(type), SDRAM_M);
// #define Free(type) memory.deallocate(type);
// #define UsedMemory() memory.getUsedMemory();
// #define ClearMemory() memory.clear();


// WAV文件头结构体
struct MemoryBlock {
    void* ptr;
    size_t blockSize;
    uint8_t mode;
};

class Memory{
private:

    // 当前已使用内存大小
    size_t usedMemory = 0;

    size_t maxUsedMemory = 0;

    //可使用内存总大小
    static const size_t MAX_MEMORY = 8 * 1024 * 1024;

    std::vector<MemoryBlock> allocations;

public:

    Memory(){}

    ~Memory();

    void begin();

    // 内存申请
    void* allocate(size_t size, uint8_t mode);

    // 内存释放
    void deallocate(void* ptr);

    // 获取当前已使用内存大小
    size_t getUsedMemory();

    void clear();

    void printMNoticeLog(const char *tag, size_t number, const char *message);
    void printMVerboseLog(const char *tag, size_t number, const char *message);

};

enum ALLOCATE_MODE
{
    SRAM_M = 0,//0.5M on GIGA R1
    SDRAM_M //8M on GIGA R1
};

extern Memory memory;

// template<typename T>
// T* pMalloc(size_t n) {
//     return static_cast<T*>(memory.allocate(n * sizeof(T), SDRAM_M));
// }

void* pMalloc(size_t n);

// template<typename T>
// void Free(T* ptr) {
//     memory.deallocate(ptr);
// }

void Free(void* ptr);

// void* Malloc(size_t size) {
//     return memory.allocate(size, SDRAM_M);
// }

// void* sMalloc(int size) {
//     return memory.allocate(size, SDRAM_M);
// }

void initMemory();

size_t UsedMemory();

void ClearMemory();

// #define Malloc(type,n) pMalloc<type>((n)*sizeof(type));
// #define Malloc(type,n) (type* )pMalloc((n)*sizeof(type));
#define Malloc(type,n) (type *)pMalloc((n)*sizeof(type));
// #define Malloc(n) sMalloc(n);

#endif // MEMORY_H